package com.flyox.game.militarychess.service;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.LinkedList;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.flyox.game.militarychess.CONSTS;
import com.flyox.game.militarychess.bean.ChessMan;
import com.flyox.game.militarychess.bean.ChessSeat;
import com.flyox.game.militarychess.bean.Player;
import com.flyox.game.militarychess.bean.Position;
import com.flyox.game.militarychess.bean.ChessMan.NAME;
import com.flyox.game.militarychess.bean.ChessSeat.SEAT_NAME;
import com.flyox.game.militarychess.bean.ChessSeat.SEAT_STATE;
import com.flyox.game.militarychess.server.services.DeskService;
import com.flyox.game.militarychess.server.services.PlayerService;
import com.flyox.game.militarychess.service.astar.FindPath;
import com.flyox.game.militarychess.service.astar.PosBean;

public class ChessService {
	private final Logger logger = LoggerFactory.getLogger(getClass());
	PlayerService playerService=new PlayerService();
	DeskService chessDeskService=new DeskService();
	/**
	 * 判断这个棋子是否是同伙
	 * @param cm
	 * @return
	 */
	public boolean sameTeamChessMan(SEAT_NAME seat1,SEAT_NAME seat2){
		if((seat1.equals(SEAT_NAME.S1)||seat1.equals(SEAT_NAME.S2)||seat1.equals(SEAT_NAME.S3)||seat1.equals(SEAT_NAME.S4))&&(seat2.equals(SEAT_NAME.S1)||seat2.equals(SEAT_NAME.S2)||seat2.equals(SEAT_NAME.S3)||seat2.equals(SEAT_NAME.S4))){
			return true;
		}
		if((seat1.equals(SEAT_NAME.S5)||seat1.equals(SEAT_NAME.S6)||seat1.equals(SEAT_NAME.S7)||seat1.equals(SEAT_NAME.S8))&&(seat2.equals(SEAT_NAME.S5)||seat2.equals(SEAT_NAME.S6)||seat2.equals(SEAT_NAME.S7)||seat2.equals(SEAT_NAME.S8))){
			return true;
		}
		return false;
	}
	
	/**
	 * 判断目标棋子是否可以和本控件棋子交换位置
	 * 调整布局时使用
	 * @param cm1
	 * @return
	 */
	public boolean canChangePos(ChessMan cm1,ChessMan cm2){
		int[][] ps=new CommonLayoutService().getPosProperties();
		
		if(cm1.getName().equals(NAME.JUNQI)){
			//当前位置不是大本营不可以
			if((ps[cm2.getPosition().row][cm2.getPosition().col]&CONSTS.POS_SUPREME_HEADQUARTER)!=CONSTS.POS_SUPREME_HEADQUARTER){
				return false;
			}
		}else if(cm2.getName().equals(NAME.JUNQI)){
			//第一个棋子不是大本营不可以
			if((ps[cm1.getPosition().row][cm1.getPosition().col]&CONSTS.POS_SUPREME_HEADQUARTER)!=CONSTS.POS_SUPREME_HEADQUARTER){
				return false;
			}
		}else if(cm1.getName().equals(NAME.DILEI)){
			if((ps[cm2.getPosition().row][cm2.getPosition().col]&(CONSTS.POS_END_LINE+CONSTS.POS_END_LINE2))==0){
				return false;
			}
		}else if(cm2.getName().equals(NAME.DILEI)){
			if((ps[cm1.getPosition().row][cm1.getPosition().col]&(CONSTS.POS_END_LINE|CONSTS.POS_END_LINE2))==0){
				return false;
			}
		}else if(cm1.getName().equals(NAME.ZHANGDAN)){
			if((ps[cm2.getPosition().row][cm2.getPosition().col]&CONSTS.POS_FIRST_LINE)==CONSTS.POS_FIRST_LINE){
				return false;
			}
		}else if(cm2.getName().equals(NAME.ZHANGDAN)){
			if((ps[cm1.getPosition().row][cm1.getPosition().col]&CONSTS.POS_FIRST_LINE)==CONSTS.POS_FIRST_LINE){
				return false;
			}
		}
		return true;
	}
	/**
	 * 判断是否有棋可走
	 * @param cm
	 * @param team
	 * @return
	 */
	public boolean haveAnyChessCanMove(ChessMan[][] cm,SEAT_NAME team){
		if(cm==null||team==null){
			return false;
		}
		int[][] ps=new CommonLayoutService().getPosProperties();
		for(int i=0;i<13;i++){
			for(int j=0;j<20;j++){
				if(cm[i][j]!=null&&cm[i][j].getTeam().equals(team)){
					if(cm[i][j].getName().equals(NAME.DILEI)||cm[i][j].getName().equals(NAME.JUNQI)){
						continue;
					}else if((ps[i][j]&(CONSTS.POS_SUPREME_HEADQUARTER))==CONSTS.POS_SUPREME_HEADQUARTER){
						continue;
					}else{
						return true;
					}
				}
			}
		}
		return false;
	}
	/**
	 * 本队伍有两人死亡则全队死亡
	 * @param p
	 * @return
	 */
	public int getTeamRes(Player p){
		int live1=0;
		int live2=0;
		p.getDeskNum();
		Hashtable<String, Player> players=playerService.getPlayers();
		Hashtable<SEAT_NAME, ChessSeat> seats=chessDeskService.getDesks().get(p.getDeskNum()).getSeats();
		if(seats.get(SEAT_NAME.S1).getPlayerID()!=null&&CONSTS.PLAYER_STATS_PLAYING==players.get(seats.get(SEAT_NAME.S1).getPlayerID()).getStates()){
			live1++;
		}
		if(seats.get(SEAT_NAME.S2).getPlayerID()!=null&&CONSTS.PLAYER_STATS_PLAYING==players.get(seats.get(SEAT_NAME.S2).getPlayerID()).getStates()){
			live1++;
		}
		if(seats.get(SEAT_NAME.S3).getPlayerID()!=null&&CONSTS.PLAYER_STATS_PLAYING==players.get(seats.get(SEAT_NAME.S3).getPlayerID()).getStates()){
			live1++;
		}
		if(seats.get(SEAT_NAME.S4).getPlayerID()!=null&&CONSTS.PLAYER_STATS_PLAYING==players.get(seats.get(SEAT_NAME.S4).getPlayerID()).getStates()){
			live1++;
		}
		//
		if(seats.get(SEAT_NAME.S5).getPlayerID()!=null&&CONSTS.PLAYER_STATS_PLAYING==players.get(seats.get(SEAT_NAME.S5).getPlayerID()).getStates()){
			live2++;
		}
		if(seats.get(SEAT_NAME.S6).getPlayerID()!=null&&CONSTS.PLAYER_STATS_PLAYING==players.get(seats.get(SEAT_NAME.S6).getPlayerID()).getStates()){
			live2++;
		}
		if(seats.get(SEAT_NAME.S7).getPlayerID()!=null&&CONSTS.PLAYER_STATS_PLAYING==players.get(seats.get(SEAT_NAME.S7).getPlayerID()).getStates()){
			live2++;
		}
		if(seats.get(SEAT_NAME.S8).getPlayerID()!=null&&CONSTS.PLAYER_STATS_PLAYING==players.get(seats.get(SEAT_NAME.S8).getPlayerID()).getStates()){
			live2++;
		}
		//
		if(p.getSeatName()==SEAT_NAME.S1||p.getSeatName()==SEAT_NAME.S2||p.getSeatName()==SEAT_NAME.S3||p.getSeatName()==SEAT_NAME.S4){
			if(live1<=2){
				return CONSTS.RESPONSE_EAT_FAIL;
			}else if(live2<=2){
				return CONSTS.RESPONSE_EAT_WIN;
			}else{
				return CONSTS.RESPONSE_EAT_CONTINUE;
			}
		}else{
			if(live2<=2){
				return CONSTS.RESPONSE_EAT_FAIL;
			}else if(live1<=2){
				return CONSTS.RESPONSE_EAT_WIN;
			}else{
				return CONSTS.RESPONSE_EAT_CONTINUE;
			}
		}
	}
	
	/**
	 * 是否可以移动棋子
	 * @param layout
	 * @param from
	 * @param to
	 * @return
	 */
	public boolean canMoveHere(ChessMan[][] layout, ChessMan from, Position to) {
		int[][] ps = new CommonLayoutService().getPosProperties();
		if (to.row >= 13 || to.col >= 20 || to.row < 0 || to.col < 0) {// 检查参数
			logger.trace("client canMoveHere paramter error");
			return false;
		}else if ((ps[from.getPosition().row][from.getPosition().col] & CONSTS.POS_SUPREME_HEADQUARTER) == CONSTS.POS_SUPREME_HEADQUARTER) {
			// 军旗位置
			logger.trace("client canMoveHere paramter error");
			return false;
		}else if (NAME.DILEI.equals(from.getName())) {
			logger.trace("client canMoveHere move DILEI error");
			// 地雷不可以动
			return false;
		}else if(from.getPosition().equals(to)){//判断重复点击
			logger.trace("client canMoveHere 重复点击");
			return false;
		}else if(layout[to.row][to.col]!=null&&layout[to.row][to.col].getName()!=NAME.EMPTY&&sameTeamChessMan(from.getTeam(),layout[to.row][to.col].getTeam())){
			//选中自己的棋子 或者同伙
			logger.trace("client canMoveHere 两次都是自己的棋或者同伙的棋");
			return false;
		}else if (layout[to.row][to.col]!= null &&layout[to.row][to.col].getName()!=NAME.EMPTY&& (ps[to.row][to.col] & CONSTS.POS_FIELD_HEADQUARTER) == CONSTS.POS_FIELD_HEADQUARTER) {
			// 目标位置是行营并且已有子不可以走
			logger.trace("client canMoveHere move to POS_FIELD_HEADQUARTER error not null");
			return false;
		}else if (Math.abs(from.getPosition().row - to.row) == 1 || Math.abs(from.getPosition().col - to.col) == 1) {
			// 先判断是否在一步范围之内 不能斜走
			if (((ps[from.getPosition().row][from.getPosition().col] & CONSTS.POS_FIELD_HEADQUARTER) == CONSTS.POS_FIELD_HEADQUARTER) || ((ps[to.row][to.col] & CONSTS.POS_FIELD_HEADQUARTER) == CONSTS.POS_FIELD_HEADQUARTER)) {
				return true;
			} else if (Math.abs(from.getPosition().row - to.row) == 1 && Math.abs(from.getPosition().col - to.col) == 1) {// 斜位
				return false;
			}else if ((ps[to.row][to.col] & CONSTS.POS_EMPTY) == CONSTS.POS_EMPTY) {
				// 目标位置是POS_EMPTY
				logger.trace("client canMoveHere move to POS_EMPTY");
				return false;
			}else if((to.row==from.getPosition().row)&&(to.row==0||to.row==2||to.row==3||to.row==4||to.row==8||to.row==9||to.row==10||to.row==12)&&(((to.col==4||to.col==9||to.col==14||to.col==15)&&(from.getPosition().col==5||from.getPosition().col==10||from.getPosition().col==15||from.getPosition().col==20))||((from.getPosition().col==4||from.getPosition().col==9||from.getPosition().col==14||from.getPosition().col==15)&&(to.col==5||to.col==10||to.col==15||to.col==20)))){
				logger.trace("client canMoveHere 在两个队伍之间的特殊位置");
				return false;
			}else{
				return true;
			}
		}else if (((ps[from.getPosition().row][from.getPosition().col] & CONSTS.POS_RAINWAY) == CONSTS.POS_RAINWAY) && ((ps[to.row][to.col] & CONSTS.POS_RAINWAY) == CONSTS.POS_RAINWAY)) {
			// 都在铁路线上  不用检查一步范围之内的情况
			if (from.getName().equals(NAME.GONGBING)) {
				// 工兵寻径算法
				FindPath fp = new FindPath(layout);
				LinkedList<PosBean> path = fp.searchPath(new PosBean(from.getPosition().row, from.getPosition().col), new PosBean(to.row, to.col));
				if (path.isEmpty()) {
					return false;
				} else {
					return true;
				}
			} else if (from.getPosition().row == to.row&&to.row==6) {//同行 特殊行
				if(from.getPosition().col>to.col){
					for(int i=to.col+1;i<from.getPosition().col;i++){
						if(i==1||i==3||i==6||i==8||i==11||i==13||i==16||i==18){
							i++;
						}
						if(i==from.getPosition().col){
							return true;
						}
						if(layout[to.row][i]!=null||((ps[to.row][i] & CONSTS.POS_RAINWAY) != CONSTS.POS_RAINWAY)){//中间不是铁路线
							return false;
						}
					}
					return true;
				}else{
					for(int i=from.getPosition().col+1;i<to.col;i++){
						if(i==1||i==3||i==6||i==8||i==11||i==13||i==16||i==18){
							i++;
						}
						if(i==to.col){
							return true;
						}
						if(layout[to.row][i]!=null||((ps[to.row][i] & CONSTS.POS_RAINWAY) != CONSTS.POS_RAINWAY)){//中间不是铁路线
							return false;
						}
					}
					return true;
				}
			}else if (from.getPosition().row == to.row) {//同行
				if(from.getPosition().col>to.col){
					for(int i=to.col+1;i<from.getPosition().col;i++){
						if(layout[to.row][i]!=null||((ps[to.row][i] & CONSTS.POS_RAINWAY) != CONSTS.POS_RAINWAY)){//中间不是铁路线
							return false;
						}
					}
					return true;
				}else{
					for(int i=from.getPosition().col+1;i<to.col;i++){
						if(layout[to.row][i]!=null||((ps[to.row][i] & CONSTS.POS_RAINWAY) != CONSTS.POS_RAINWAY)){//中间不是铁路线
							return false;
						}
					}
					return true;
				}
			} else if (from.getPosition().col == to.col) {//同列
				if(from.getPosition().row>to.row){
					for(int i=to.row+1;i<from.getPosition().row;i++){
						if(layout[i][to.col]!=null){
							return false;
						}
					}
					return true;
				}else{
					for(int i=from.getPosition().row+1;i<to.row;i++){
						if(layout[i][to.col]!=null){
							return false;
						}
					}
					return true;
				}
			} else {// 不在同一条线上
				return false;
			}
		} else {// 不是铁路线 不能到达 因为不在一步之内
			return false;
		}
	}

	/**
	 * 判断是否所有人都同意开始
	 * 暂时只判断两个人 测试用
	 * @param seats
	 * @return
	 */
	public boolean isAllReady(Hashtable<SEAT_NAME, ChessSeat> seats) {
		
		Enumeration<ChessSeat> chessSeats=seats.elements();
		while(chessSeats.hasMoreElements()){
			ChessSeat cs=chessSeats.nextElement();
			if(SEAT_STATE.EMPTY.equals(cs.getSeatState())){
				return false;
			}
			Player p=playerService.getPlayer(cs.getPlayerID());
			if(p==null){
				return false;
			}if(p.getStates()!=CONSTS.PLAYER_STATS_READY){
				return false;
			}
		}
		return true;
		
	}
}
